//
//  user.v
//
//  Generische Slave-Mode Anwendung: Realisiert ein les-/schreibbares
//  Hardware-Register
//

module user(
	    CLK,
	    RESET,  
	    ADDRESSED,
	    WRITE,
	    DATAIN,
	    DATAOUT,
	    ADDRESS,
	    IRQ
	    );

   // Eingaenge
   input           CLK;
   input           RESET;
   input           ADDRESSED;
   input           WRITE;
   input [31:0]    DATAIN;
   input [23:2]    ADDRESS;

   reg [23:2] 	   addresses [0:10];
   reg [7:0] 	   results [0:7];
   
   // Ausgaenge
   output [31:0]   DATAOUT;
   output          IRQ;

   wire 	   IRQ = 1'b0; // wird im Slave-Mode nicht gebraucht

   reg [7:0] 	   dividend, divisor;
   wire [7:0] 	   quot, remd;	   
   
   PipelinedDivider pd(.dividend(dividend),
		       .divisor(divisor),
		       .quot(quot),
		       .remd(remd),
		       .clk(CLK),
		       .rfd());
   
   localparam DIVIDEND = 1'b0;
   localparam DIVISOR = 1'b1;
   
   // Beginn der Anwendung **************************************************

   // Ausgabedaten auf Bus legen
   assign DATAOUT = results[ADDRESS[4:2]];

   
   generate
      genvar 	   i;
      for (i = 1; i < 11; i = i + 1) begin
	 always @(posedge CLK or posedge RESET) begin
	    if ((RESET) || (WRITE == 0)) begin
	       addresses[i] <= 22'hFFFFFF;
	    end else begin
	       addresses[i] <= addresses[i - 1];
	    end
	 end
      end
   endgenerate
   
   always @(posedge CLK or posedge RESET) begin
      // Initialisiere Register
      if (RESET) begin
	 addresses[0] <= 22'hFFFFFF;
	 dividend  <= 32'hDEADBEEF;
	 divisor  <= 32'hDEADBEEF;
	 results[0] <= 0;
	 results[1] <= 0;
	 results[2] <= 0;
	 results[3] <= 0;
	 results[4] <= 0;
	 results[5] <= 0;
	 results[6] <= 0;
	 results[7] <= 0;
	 // Schreibzugriff auf RC
      end else begin // if (RESET)

	 if (addresses[10] !=  22'hFFFFFF) begin
	    results[addresses[10]-1] <= remd;
	    results[addresses[10]] <= quot;
	 end
	 
	 if (ADDRESSED && WRITE) begin
	    
	    case (ADDRESS[2:2])
	      DIVIDEND:begin
		 dividend <= DATAIN[7:0];
		 addresses[0] <= 22'hFFFFFF;
	      end	      
	      DIVISOR: begin
		 divisor <= DATAIN[7:0];
		 addresses[0] <= ADDRESS;
	      end
	    endcase // case (ADDRESS[3:2])
	    
	 end else begin
	    addresses[0] <= 22'hFFFFFF;
	    
	 end
      end
      
   end // always @ (posedge CLK or posedge RESET)
   
endmodule
